package com.bluesky.javawebbrowser.domain.html.tags;

import com.bluesky.javawebbrowser.domain.html.tags.form.Form;
import com.bluesky.javawebbrowser.domain.html.tags.form.TextArea;
import com.bluesky.javawebbrowser.domain.html.tags.form.input.Input;
import com.bluesky.javawebbrowser.domain.html.tags.form.select.Option;
import com.bluesky.javawebbrowser.domain.html.tags.form.select.Select;
import com.bluesky.javawebbrowser.domain.html.tags.table.TD;
import com.bluesky.javawebbrowser.domain.html.tags.table.TR;
import com.bluesky.javawebbrowser.domain.html.tags.table.Table;

public enum TagType {
	HTML, HEAD, HR, TITLE {

		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Title)
				return tag;

			return new Title(tag);
		}

	},
	TT, BASE {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	BASEFONT, BDO, BIG, BLOCKQUOTE, B, BODY {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Body)
				return tag;

			return new Body(tag);
		}
	},
	BR {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	P {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof P)
				return tag;

			return new P(tag);
		}
	},
	SPAN, H1, H2, H3, H4, H5, H6, A {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof A)
				return tag;

			return new A(tag);
		}
	},
	ABBR, ACRONYM, ADDRESS, APPLET, AREA {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	FORM {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Form)
				return tag;

			return new Form(tag);
		}
	},
	FRAME, FRAMESET, TABLE {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Table)
				return tag;

			return new Table(tag);
		}
	},
	THEAD, TBODY, TFOOT, TH, TR {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof TR)
				return tag;

			return new TR(tag);
		}
	},
	TD {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof TD)
				return tag;
			return new TD(tag);
		}
	},
	UL, U, VAR, LABEL, LENGEND, LI, DD, DEL, DFN, DIR, DIV {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Div)
				return tag;
			return new Div(tag);
		}
	},
	DL, DT, EM, FIELDSET, FONT, LINK {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	INPUT {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Input)
				return tag;

			Input input = new Input(tag);
			// Tag -> InputTag -> TextTag or Checkbox Tag,..etc.
			Input input2 = input.getType().upgrade(input);
			return input2;
		}

		@Override
		public boolean isSolo() {
			return true;
		}
	},
	INS, ISINDEX, I, KBD, SELECT {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Select)
				return tag;

			return new Select(tag);

		}
	},
	SMALL, STRIKE, STYLE, SUB, SUP, OL, OPTGROUP, OPTION {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Option)
				return tag;

			return new Option(tag);

		}

	},
	OBJECT, PARAM, PRE, Q, IFRAME, IMG {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Img)
				return tag;

			return new Img(tag);

		}

		@Override
		public boolean isSolo() {

			return true;
		}
	},
	CAPTION, CENTER, CITE, CODE,
	/**
	 * comment tag is start with '<!' and end with '-->'
	 */
	COMMENT {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Comment)
				return tag;

			return new Comment(tag);

		}

		@Override
		public boolean isSolo() {
			return true;
		}

		@Override
		public boolean isOneTextChildOnly() {

			return true;
		}
	},
	SPACER {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	S, SAMP, SCRIPT {
		@Override
		public boolean isOneTextChildOnly() {
			return true;
		}
	},
	STRONG,
	/**
	 * it is not mentioned in the HTML spec, it is the text block in tag P or
	 * TD.
	 */
	TEXT_BLOCK {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof TextBlock)
				return tag;

			return new TextBlock(tag);
		}
	},
	TEXTAREA {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof TextArea)
				return tag;

			return new TextArea(tag);
		}

		@Override
		public boolean isOneTextChildOnly() {

			return true;
		}
	},
	MAP, MENU, META {
		@Override
		public boolean isSolo() {
			return true;
		}
	},
	NOFRAME, NOSCRIPT, DOCTYPE {
		@Override
		public boolean isSolo() {

			return true;
		}
	},
	/**
	 * It is another fake tag
	 */
	ROOT {
		@Override
		public Tag upgrade(Tag tag) {
			if (tag instanceof Root)
				return tag;

			return new Root(tag);

		}
	},
	/**
	 * it is for extend
	 */
	COMPONENT, COL, COLGROUP, UNKNOWN;

	public Tag upgrade(Tag tag) {
		return tag;
	}

	public static TagType getType(String name) {

		if (name.startsWith("!"))
			return COMMENT;

		TagType t = valueOf(name);
		return t;

	}

	public boolean isSolo() {
		return false;
	}

	/**
	 * only child is allowed. and the child tag is treated as TEXT_BLOCK
	 * 
	 * @return
	 */
	public boolean isOneTextChildOnly() {
		return false;
	}

}
